using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.IO;
using System.ComponentModel;

namespace TTCaller
{


    public class Sound
    {

        private byte[] m_soundBytes;

        private string m_fileName;



        private enum Flags
        {

            SND_SYNC = 0x0000,  /* play synchronously (default) */

            SND_ASYNC = 0x0001,  /* play asynchronously */

            SND_NODEFAULT = 0x0002,  /* silence (!default) if sound not found */

            SND_MEMORY = 0x0004,  /* pszSound points to a memory file */

            SND_LOOP = 0x0008,  /* loop the sound until next sndPlaySound */

            SND_NOSTOP = 0x0010,  /* don't stop any currently playing sound */

            SND_NOWAIT = 0x00002000, /* don't wait if the driver is busy */

            SND_ALIAS = 0x00010000, /* name is a registry alias */

            SND_ALIAS_ID = 0x00110000, /* alias is a predefined ID */

            SND_FILENAME = 0x00020000, /* name is file name */

            SND_RESOURCE = 0x00040004  /* name is resource name or atom */

        }



        [DllImport("CoreDll.DLL", EntryPoint = "PlaySound", SetLastError = true)]

        private extern static int WCE_PlaySound(string szSound, IntPtr hMod, int flags);



        [DllImport("CoreDll.DLL", EntryPoint = "PlaySound", SetLastError = true)]

        private extern static int WCE_PlaySoundBytes(byte[] szSound, IntPtr hMod, int flags);


        [DllImport("coredll.dll")]
        public static extern int waveOutGetVolume(IntPtr hwo, out uint dwVolume);

        [DllImport("coredll.dll")]
        public static extern int waveOutSetVolume(IntPtr hwo, uint dwVolume); 


        /// <summary>

        /// Construct the Sound object to play sound data from the specified file.

        /// </summary>

        public Sound(string fileName)
        {

            m_fileName = Form_Main.Main.StartLoc + fileName;

        }



        /// <summary>

        /// Construct the Sound object to play sound data from the specified stream.

        /// </summary>

        public Sound(Stream stream)
        {

            // read the data from the stream

            m_soundBytes = new byte[stream.Length];

            stream.Read(m_soundBytes, 0, (int)stream.Length);

        }



        /// <summary>

        /// Play the sound

        /// </summary>

        public void Play()
        {

            // if a file name has been registered, call WCE_PlaySound,

            //  otherwise call WCE_PlaySoundBytes

            if (m_fileName != null)

                WCE_PlaySound(m_fileName, IntPtr.Zero, (int)(Flags.SND_ASYNC | Flags.SND_FILENAME | Flags.SND_NOSTOP));

            else

                WCE_PlaySoundBytes(m_soundBytes, IntPtr.Zero, (int)(Flags.SND_ASYNC | Flags.SND_MEMORY | Flags.SND_NOSTOP));

        }

        

    }

    public class  SoundManager
    {

        Sound m_soundJobAsk;
        Sound m_soundJobGot;
        Sound m_soundMsgRecv;
        Sound m_soundPickup;
        Sound m_soundFree;
        Sound m_soundWelcome;

        static SoundManager m_Instance = new SoundManager();

        static public SoundManager getInstance()
        {
            return m_Instance;
        }

        static public void UpVolume()
        {
            uint ui = new uint();
            Sound.waveOutGetVolume(IntPtr.Zero, out ui);
            ui = ui + 1;
            Sound.waveOutSetVolume(IntPtr.Zero, ui);
        }

        static public void DownVolume()
        {
            uint ui = new uint();
            Sound.waveOutGetVolume(IntPtr.Zero, out ui);
            ui = ui - 1;
            if (ui < 0)
                ui = 0;
            Sound.waveOutSetVolume(IntPtr.Zero, ui);
        }


        private  SoundManager()
        {
            m_soundJobAsk = new Sound("JobAsk.wav");
            m_soundJobGot = new Sound("JobGot.wav");
            m_soundMsgRecv = new Sound("MsgRecv.wav");
            m_soundPickup = new Sound("Pickup.wav");
            m_soundFree = new Sound("Free.wav");
            m_soundWelcome = new Sound("Welcome.wav");

        }

        public void playJobAsk()
        {
            m_soundJobAsk.Play();
        }

        public void playJobGot()
        {
            m_soundJobGot.Play();
        }
        public void playMsgRecv()
        {
            m_soundMsgRecv.Play();
        }
        public void playPickup()
        {
            m_soundPickup.Play();
        }
        public void playFree()
        {
            m_soundFree.Play();
        }

        public bool m_bPlayWelcome = false;

        public void playWelcome()
        {
            if (!m_bPlayWelcome)
            {
                m_bPlayWelcome = true;
                m_soundWelcome.Play();
            }
        }


    }

    public class DeviceManager
    {

        public struct SYSTEMTIME
        {
            public ushort wYear;
            public ushort wMonth;
            public ushort wDayOfWeek;
            public ushort wDay;
            public ushort wHour;
            public ushort wMinute;
            public ushort wSecond;
            public ushort wMilliseconds;
        }


         [DllImport("coredll.dll")]
        public extern static void GetSystemTime(ref SYSTEMTIME lpSystemTime);
         [DllImport("coredll.dll")]
        public extern static uint SetSystemTime(ref SYSTEMTIME lpSystemTime);

        static DeviceManager m_Instance = new DeviceManager();

        static public DeviceManager getInstance()
        {
            return m_Instance;
        }


        public class SYSTEM_POWER_STATUS_EX2
        {
            public byte ACLineStatus;
            public byte BatteryFlag;
            public byte BatteryLifePercent;
            public byte Reserved1;
            public uint BatteryLifeTime;
            public uint BatteryFullLifeTime;
            public byte Reserved2;
            public byte BackupBatteryFlag;
            public byte BackupBatteryLifePercent;
            public byte Reserved3;
            public uint BackupBatteryLifeTime;
            public uint BackupBatteryFullLifeTime;
            public uint BatteryVoltage;
            public uint BatteryCurrent;
            public uint BatteryAverageCurrent;
            public uint BatteryAverageInterval;
            public uint BatterymAHourConsumed;
            public uint BatteryTemperature;
            public uint BackupBatteryVoltage;
            public byte BatteryChemistry;
        }

        public class SYSTEM_POWER_STATUS_EX
        {
            public byte ACLineStatus;
            public byte BatteryFlag;
            public byte BatteryLifePercent;
            public byte Reserved1;
            public uint BatteryLifeTime;
            public uint BatteryFullLifeTime;
            public byte Reserved2;
            public byte BackupBatteryFlag;
            public byte BackupBatteryLifePercent;
            public byte Reserved3;
            public uint BackupBatteryLifeTime;
            public uint BackupBatteryFullLifeTime;
        }
        [DllImport("coredll")]
        private static extern uint GetSystemPowerStatusEx(SYSTEM_POWER_STATUS_EX lpSystemPowerStatus, bool fUpdate);

        [DllImport("coredll")]
        private static extern uint GetSystemPowerStatusEx2(SYSTEM_POWER_STATUS_EX2 lpSystemPowerStatus, uint dwLen, bool fUpdate);


        public int getPowerExt()
        {
            SYSTEM_POWER_STATUS_EX status = new SYSTEM_POWER_STATUS_EX();
            //SYSTEM_POWER_STATUS_EX2 status2 = new SYSTEM_POWER_STATUS_EX2();

            if (GetSystemPowerStatusEx(status, false) == 1)
            {
                LogManager.getInstance().Log("PowerP:" + String.Format("{0}%", status.BatteryLifePercent) + "PowerT:" + String.Format("{0}", status.BatteryLifeTime.ToString()));
                return (int)System.Convert.ToInt16(status.BatteryLifePercent);
            }
            return -1;

            /*if (GetSystemPowerStatusEx2(status2,(uint)Marshal.SizeOf(status2), false) == (uint)Marshal.SizeOf(status2))
            {
                LogManager.getInstance().Log("PowerE2:" + String.Format("{0}%", status2.BackupBatteryLifePercent));
            }*/
        }
        public bool IsLowBattery(int arg_nPercent)
        {
            if (getPowerExt() < arg_nPercent)
            {
                return true;
            }
            return false;
        }

        private DeviceManager()
        {
        }

        static public uint readSettingValue(string arg_strPath, string arg_strKey,object arg_objDefault)
        {
            string strTemp = "";
            try
            {
                //LogManager.getInstance().Log("ReadVal:" + arg_strPath + arg_strKey + arg_objDefault.ToString());

                strTemp = System.Convert.ToString(Microsoft.Win32.Registry.GetValue(arg_strPath, arg_strKey, arg_objDefault));
                //LogManager.getInstance().Log("ReadVal:" + strTemp);

                return System.Convert.ToUInt32(strTemp);
            }
            catch (Exception ex)
            {
                //System.Windows.Forms.MessageBox.Show(arg_strKey + " setValError:" + strTemp);
                
            }
            return 0;
        }
        [DllImport("coredll")]
        extern static void ReleaseDC(IntPtr hWnd, IntPtr hDC);
        [DllImport("coredll")]
        extern static IntPtr ExtEscape(IntPtr hDC, int Esc, int cbInData, int[] InData, int cbOutData, IntPtr OutData);
        [DllImport("coredll")]
        private static extern IntPtr GetDC(IntPtr hwnd);

        //	ExtEscape(::GetDC(NULL), DRVESC_SET_BACKLIGHT_INTENSITY, sizeof(UINT32), (LPCSTR)&intensity, 0, NULL);
        [DllImport("coredll.dll", EntryPoint = "waveOutSetVolume")]
        extern static Int32 waveOutSetVolume(IntPtr hwo, uint dwVolume);

        static public void setVolume(uint arg_nVol)
        {
            Microsoft.Win32.Registry.SetValue(@"HKEY_CURRENT_USER\ControlPanel\Volume", "Volume", arg_nVol); //0~4294967295
            waveOutSetVolume(IntPtr.Zero, arg_nVol);
        }

        static public uint readVolume()
        {
            uint u = readSettingValue(@"HKEY_CURRENT_USER\ControlPanel\Volume", "Volume", 3865437797);
            

            return u;
        }


        static public void setBackLightOff()
        {
            LogManager.getInstance().Log("SetBLOFF");
            int[] nary = new int[1];
            nary[0] = 1;
            ExtEscape(GetDC(Form_Main.Main.Handle), 100003, sizeof(UInt32), nary, 0, Form_Main.Main.Handle);
        }

        static public void setBackLightOn()
        {
            uint u = readSettingValue(@"HKEY_CURRENT_USER\ControlPanel\BackLight", "ACBrightness", 55);
            int[] nary = new int[1];
            nary[0] = System.Convert.ToInt32(u);
            ExtEscape(GetDC(Form_Main.Main.Handle), 100003, sizeof(UInt32), nary, 0, Form_Main.Main.Handle);
        }

        static public uint readBackLightValue()
        {
            uint u = readSettingValue(@"HKEY_CURRENT_USER\ControlPanel\BackLight", "ACBrightness", 55);

            return u;
        }

        static public void setBackLightValue(uint arg_nVal)
        {
            LogManager.getInstance().Log("SetBLVal:" + arg_nVal.ToString());
            uint nTempValue = arg_nVal;
            if (nTempValue > 128)
                nTempValue = 128;
            if (nTempValue < 1)
                nTempValue = 1;
            LogManager.getInstance().Log("SetBLVal:" + nTempValue.ToString());
            Microsoft.Win32.Registry.SetValue(@"HKEY_CURRENT_USER\ControlPanel\BackLight", "ACBrightness", System.Convert.ToString(nTempValue)); // 1
            int[] nary = new int[1];
            nary[0] = System.Convert.ToInt32(nTempValue);
            ExtEscape(GetDC(Form_Main.Main.Handle), 100003, sizeof(UInt32), nary, 0, Form_Main.Main.Handle);
        }

        static public uint readBackLightTimeOut()
        {
            uint u = readSettingValue(@"HKEY_CURRENT_USER\ControlPanel\BackLight", "MyTimeOut", 60);

            return u;
        }

        static public void setBackLightTimeOut(uint arg_nVal)
        {
            Microsoft.Win32.Registry.SetValue(@"HKEY_CURRENT_USER\ControlPanel\BackLight", "MyTimeOut", System.Convert.ToString(arg_nVal)); // 1
            Form_Main.Main.resetBackLightTimeout();
        }




        static public void setSettingValue(string arg_strPath, string arg_strKey, object arg_objVal, string arg_strEvent)
        {
            LogManager.getInstance().Log("SetVal:" + arg_strPath);

            LogManager.getInstance().Log("SetVal:" + arg_strKey);
            LogManager.getInstance().Log("SetVal:" +arg_objVal.ToString());

            //RegistryKey regBacklight = Registry.CurrentUser.OpenSubKey(@"\ControlPanel\backlight", true);
            //LogManager.getInstance().Log("OriVal:" + regBacklight.GetValue(arg_strKey));

            //regBacklight.SetValue(arg_strKey, arg_objVal);

            Microsoft.Win32.Registry.SetValue(arg_strPath, arg_strKey, System.Convert.ToString(arg_objVal)); // 1

            //RegistryKey regBacklightReloadEventname = Registry.LocalMachine.OpenSubKey(@"\Drivers\BuiltIn\backlight");

            //string eventString = (String)regBacklightReloadEventname.GetValue("ReloadEventName");
            //LogManager.getInstance().Log("EventName:" + eventString);

            //RaiseChangeEvent(arg_strEvent);

            byte[] bary = System.Text.Encoding.Default.GetBytes(arg_objVal.ToString());
            int[] nary = new int[1];

            /*for (int i = 0; i < bary.Length; i++)
            {
                nary[i] = (int)bary[i];
            }*/

            nary[0] = System.Convert.ToInt32(arg_objVal);

            ExtEscape(GetDC(Form_Main.Main.Handle), 100003,sizeof(UInt32), nary, 0, Form_Main.Main.Handle);

        }

        public void OpenBackLight()
        {
            //HKEY_CURRENT_USER\ControlPanel\BackLight
            Microsoft.Win32.Registry.SetValue(@"HKEY_CURRENT_USER\ControlPanel\BackLight", "UseExt", 1); // 1
            Microsoft.Win32.Registry.SetValue(@"HKEY_CURRENT_USER\ControlPanel\BackLight", "ACTimeout", 15); // 15 sec
            Microsoft.Win32.Registry.SetValue(@"HKEY_CURRENT_USER\ControlPanel\BackLight", "UseBattery", 1); // 1
            Microsoft.Win32.Registry.SetValue(@"HKEY_CURRENT_USER\ControlPanel\BackLight", "BatteryTimeout", 15); // 15 sec



            Microsoft.Win32.Registry.SetValue(@"HKEY_CURRENT_USER\ControlPanel\BackLight", "BacklightLevel", 100); // 100
            //Microsoft.Win32.Registry.SetValue(@"HKEY_CURRENT_USER\ControlPanel\BackLight", "ACTimeout");
            //Microsoft.Win32.Registry.SetValue(@"HKEY_CURRENT_USER\ControlPanel\BackLight", "ACTimeout");



            Microsoft.Win32.Registry.SetValue(@"HKEY_CURRENT_USER\ControlPanel\Volume", "Volume", 4294967295); //0~4294967295

        }

        public int Brightness
        {

            set
            {
                SetBacklightValue("ACBrightness", value);
                SetBacklightValue("Brightness", value);

               // RaiseBackLightChangeEvent();
            }
        }

        public int RceLcdLightSetValue(int Light)
        {
            /*
	        UInt32 intensity = System.Convert.ToUInt32(Light);
	        ExtEscape(GetDC(NULL), DRVESC_SET_BACKLIGHT_INTENSITY, 
	        sizeof(UINT32), (LPCSTR)&intensity, 0, NULL);

	        return Light;
            */
            return 0;
        }


        private void SetBacklightValue(string name, int v)
        {
            RegistryKey key =
               Registry.CurrentUser.OpenSubKey(@"ControlPanel\Backlight", true);
            if (key != null)
            {
                key.SetValue(name, v);
                key.Close();
            }
        }

        [DllImport("coredll.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern  IntPtr CreateEvent(IntPtr lpSecurityAttributes, bool isManualReset, bool initialState, string name);
        [DllImport("coredll.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern int CloseHandle(IntPtr hObject);
       // [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        //internal static extern int SetEvent(IntPtr hObject);

        [DllImport("coredll.dll", EntryPoint = "EventModify", SetLastError = true)]
        private static extern int EventModify(IntPtr hEvent, EventAction action);

        private enum EventAction : uint
        {
            EVENT_PULSE = 1,
            EVENT_RESET = 2,
            EVENT_SET = 3
        }

        private static bool SetEvent(IntPtr hEvent)
        {
            return Convert.ToBoolean(EventModify(hEvent, EventAction.EVENT_SET));
        }
        private static bool ResetEvent(IntPtr hEvent)
        {
            return Convert.ToBoolean(EventModify(hEvent, EventAction.EVENT_RESET));
        }
        private static bool PulseEvent(IntPtr hEvent)
        {
            return Convert.ToBoolean(EventModify(hEvent, EventAction.EVENT_PULSE));
        }

        private static void RaiseChangeEvent(string arg_strEventName)
        {
            /*
            IntPtr hBackLightEvent = CreateEvent(IntPtr.Zero, false, true, arg_strEventName);
            if (hBackLightEvent != IntPtr.Zero)
            {
                SetEvent(hBackLightEvent);
                CloseHandle(hBackLightEvent);
                LogManager.getInstance().Log("Raise " + arg_strEventName + " OK");
            }
             * 
             */
            LogManager.getInstance().Log("Raise " + arg_strEventName + " Start");

            IntPtr newHandle = IntPtr.Zero;

            try
            {

                newHandle = CreateEvent(IntPtr.Zero, false, true, arg_strEventName);

                EventModify(newHandle, EventAction.EVENT_SET);

                CloseHandle(newHandle);
                LogManager.getInstance().Log("Raise " + arg_strEventName + " OK");

            }

            finally
            {

                newHandle = IntPtr.Zero;

            }
            LogManager.getInstance().Log("Raise " + arg_strEventName + " End");

        }

        public void CloseBackLight()
        {
            //HKEY_CURRENT_USER\ControlPanel\BackLight

           
        }


    }
    public class Screen
    {

        private const uint QUERYESCSUPPORT = 8;
        private const uint GETVFRAMEPHYSICAL = 6144;
        private const uint GETVFRAMELEN = 6145;
        private const uint DBGDRIVERSTAT = 6146;
        private const uint SETPOWERMANAGEMENT = 6147;
        private const uint GETPOWERMANAGEMENT = 6148;
        private const int SHFS_SHOWSTARTICON = 0x0010;
        private const int SHFS_HIDESTARTICON = 0x0020;
        public static void PowerOff()
        {
            IntPtr hdc = GetDC(IntPtr.Zero);
            uint size = 12;
            byte[] vpm = new byte[size];
            BitConverter.GetBytes(size).CopyTo(vpm, 0);
            BitConverter.GetBytes(0x0001).CopyTo(vpm, 4);
            BitConverter.GetBytes((uint)ScreenPowerState.ScreenPowerOff).CopyTo(vpm, 8);
            ExtEscapeSet(hdc, SETPOWERMANAGEMENT, size, vpm, 0, IntPtr.Zero);
        }

        public static void PowerOn()
        {
            IntPtr hdc = GetDC(IntPtr.Zero);

            uint size = 12;
            byte[] vpm = new byte[size];

            BitConverter.GetBytes(size).CopyTo(vpm, 0);
            BitConverter.GetBytes(0x0001).CopyTo(vpm, 4);
            BitConverter.GetBytes((uint)ScreenPowerState.ScreenPowerOn).CopyTo(vpm, 8);

            ExtEscapeSet(hdc, SETPOWERMANAGEMENT, size, vpm, 0, IntPtr.Zero);
        }

        [DllImport("coredll", EntryPoint = "ExtEscape")]
        private static extern int ExtEscapeSet(
            IntPtr hdc,
            uint nEscape,
            uint cbInput,
            byte[] lpszInData,
            int cbOutput,
            IntPtr lpszOutData
            );

        [DllImport("coredll")]
        private static extern IntPtr GetDC(IntPtr hwnd);
    }

    public enum ScreenPowerState : uint
    {
        ScreenPowerOn = 1,
        ScreenPowerStandBy,
        ScreenPowerSuspend,
        ScreenPowerOff
    }


}
